#pragma once
#include <memory>
#include <functional>
#include <string>
#include "fields.hpp"

namespace rpc
{
    //基类消息
    class BaseMessage
    {
    public:
        using ptr = std::shared_ptr<BaseMessage>;
        virtual ~BaseMessage() {}
        virtual void setId(const std::string &id) { _rid = id; } //设置id
        virtual std::string rid() { return _rid; } //获取id
        virtual void setMType(MType mtype) { _mtype = mtype; } //设置消息类型
        virtual MType mtype() { return _mtype; }//获取消息类型
        virtual std::string serialize() = 0; //序列化
        virtual bool unserialize(const std::string &msg) = 0; //反序列化
        virtual bool check() = 0;//校验消息
    private:
        MType _mtype; //消息类型
        std::string _rid;//uuid,请求id
    };

    //基类缓冲区
    class BaseBuffer
    {
    public:
        using ptr = std::shared_ptr<BaseBuffer>;
        virtual size_t readableSize() = 0;//缓冲区可读数据大小
        virtual int32_t PeekInt32() = 0;//尝试获取四字节数据
        virtual void retrieveInt32() = 0;//删除缓冲区前四字节数据
        virtual int32_t readInt32() = 0;//PeekInt32()+retrieveInt32()
        virtual std::string retrieveAsString(size_t len) = 0;//取出指定长度的字符串
    };

    //基类协议
    class BaseProtocol
    {
    public:
        using ptr = std::shared_ptr<BaseProtocol>;
        virtual bool canProcessed(const BaseBuffer::ptr &buf) = 0;//是否能够处理一条消息
        virtual bool onMessage(const BaseBuffer::ptr &buf, BaseMessage::ptr &msg) = 0;//读取缓冲区的内容到一个消息对象中
        virtual std::string serialize(const BaseMessage::ptr &msg) = 0;//序列化消息
    };

    //基类连接对象
    class BaseConnection
    {
    public:
        using ptr = std::shared_ptr<BaseConnection>;
        virtual void send(const BaseMessage::ptr &msg) = 0;//发送消息
        virtual void shutdown() = 0;//关闭连接
        virtual bool connected() = 0;//判断连接是否正常
    };

    using ConnectionCallback = std::function<void(const BaseConnection::ptr &)>;
    using CloseCallback = std::function<void(const BaseConnection::ptr &)>;
    using MessageCallback = std::function<void(const BaseConnection::ptr &, BaseMessage::ptr &)>;

    //基类服务端
    class BaseServer
    {
    public:
        using ptr = std::shared_ptr<BaseServer>;
        virtual void start() = 0;//服务器启动
        virtual void setConnectionCallback(const ConnectionCallback &cb)//设置连接建立的回调函数
        {
            _cb_connection = cb;
        }
        virtual void setCloseCallback(const CloseCallback &cb)//设置连接关闭的回调函数
        {
            _cb_close = cb;
        }
        virtual void setMessageCallback(const MessageCallback &cb)//设置消息处理的回调函数
        {
            _cb_message = cb;
        }

    protected:
        ConnectionCallback _cb_connection;//连接建立
        CloseCallback _cb_close;//连接关闭
        MessageCallback _cb_message;//消息
    };

    //基类客户端
    class BaseClient
    {
    public:
        using ptr = std::shared_ptr<BaseClient>;
        virtual void connect() = 0;//连接服务器
        virtual void shutdown() = 0;//关闭连接
        virtual bool send(const BaseMessage::ptr &) = 0;//发送消息
        virtual BaseConnection::ptr connection() = 0;//获取连接对象
        virtual bool connected() = 0;//判断连接是否正常
        virtual void setConnectionCallback(const ConnectionCallback &cb)
        {
            _cb_connection = cb;
        }
        virtual void setCloseCallback(const CloseCallback &cb)
        {
            _cb_close = cb;
        }
        virtual void setMessageCallback(const MessageCallback &cb)
        {
            _cb_message = cb;
        }
    protected:
        ConnectionCallback _cb_connection;
        CloseCallback _cb_close;
        MessageCallback _cb_message;
    };
}